﻿namespace Smart.Utils.Net
{
    using System;
    using System.IO;
    using System.Net;

    internal class DownloadData
    {
        private IWebProxy proxy;
        private WebResponse response;
        private long size;
        private long start;
        private Stream stream;

        private DownloadData()
        {
            this.proxy = null;
        }

        private DownloadData(WebResponse response, long size, long start)
        {
            this.proxy = null;
            this.response = response;
            this.size = size;
            this.start = start;
            this.stream = null;
        }

        public void Close()
        {
            this.response.Close();
        }

        public static DownloadData Create(string url, string destFolder)
        {
            return Create(url, destFolder, null);
        }

        public static DownloadData Create(string url, string destFolder, IWebProxy proxy)
        {
            DownloadData data = new DownloadData();
            data.proxy = proxy;
            long fileSize = data.GetFileSize(url);
            data.size = fileSize;
            WebRequest request = data.GetRequest(url);
            try
            {
                data.response = request.GetResponse();
            }
            catch (Exception exception)
            {
                throw new ArgumentException(string.Format("Error downloading \"{0}\": {1}", url, exception.Message), exception);
            }
            ValidateResponse(data.response, url);
            string fileName = Path.GetFileName(data.response.ResponseUri.ToString());
            string path = Path.Combine(destFolder, fileName);
            if (!(data.IsProgressKnown || !System.IO.File.Exists(path)))
            {
                System.IO.File.Delete(path);
            }
            if (data.IsProgressKnown && System.IO.File.Exists(path))
            {
                if (!(data.Response is HttpWebResponse))
                {
                    System.IO.File.Delete(path);
                    return data;
                }
                data.start = new FileInfo(path).Length;
                if (data.start > fileSize)
                {
                    System.IO.File.Delete(path);
                    return data;
                }
                if (data.start >= fileSize)
                {
                    return data;
                }
                data.response.Close();
                request = data.GetRequest(url);
                ((HttpWebRequest) request).AddRange((int) data.start);
                data.response = request.GetResponse();
                if (((HttpWebResponse) data.Response).StatusCode != HttpStatusCode.PartialContent)
                {
                    System.IO.File.Delete(path);
                    data.start = 0L;
                }
            }
            return data;
        }

        private long GetFileSize(string url)
        {
            WebResponse response = null;
            long contentLength = -1L;
            try
            {
                response = this.GetRequest(url).GetResponse();
                contentLength = response.ContentLength;
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
            }
            return contentLength;
        }

        private WebRequest GetRequest(string url)
        {
            WebRequest request = WebRequest.Create(url);
            if (request is HttpWebRequest)
            {
                request.Credentials = CredentialCache.DefaultCredentials;
                Uri proxy = request.Proxy.GetProxy(new Uri("http://www.google.com"));
            }
            if (this.proxy != null)
            {
                request.Proxy = this.proxy;
            }
            return request;
        }

        private static void ValidateResponse(WebResponse response, string url)
        {
            if (response is HttpWebResponse)
            {
                HttpWebResponse response2 = (HttpWebResponse) response;
                if (response2.ContentType.Contains("text/html") || (response2.StatusCode == HttpStatusCode.NotFound))
                {
                    throw new ArgumentException(string.Format("Could not download \"{0}\" - a web page was returned from the web server.", url));
                }
            }
            else if (response is FtpWebResponse)
            {
                FtpWebResponse response3 = (FtpWebResponse) response;
                if (response3.StatusCode == FtpStatusCode.ConnectionClosed)
                {
                    throw new ArgumentException(string.Format("Could not download \"{0}\" - FTP server closed the connection.", url));
                }
            }
        }

        public Stream DownloadStream
        {
            get
            {
                if (this.start == this.size)
                {
                    return Stream.Null;
                }
                if (this.stream == null)
                {
                    this.stream = this.response.GetResponseStream();
                }
                return this.stream;
            }
        }

        public long FileSize
        {
            get
            {
                return this.size;
            }
        }

        public bool IsProgressKnown
        {
            get
            {
                return (this.size > -1L);
            }
        }

        public WebResponse Response
        {
            get
            {
                return this.response;
            }
            set
            {
                this.response = value;
            }
        }

        public long StartPoint
        {
            get
            {
                return this.start;
            }
        }
    }
}

